home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
Xprof
/
xmeasure
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
15KB
|
567 lines
/*==================================================================
* File : main.c
* Package: Xmeasure
*
* Author : Aloke Gupta.
*
* (C) Copyright 1992, Aloke Gupta.
* All rights granted to University of Illinois Board of Regents.
*==================================================================*/
/*
* int main(int argc, char *argv[])
* int SetupDisplay(XD *xd)
* int CleanupDisplay(XD *xd)
* int ParkPointer(XD *xd);
* int PrintServerInfo(FILE *fp, XD *xd, int argc, char **argv)
* int Usage(char *errmsg)
* int ListRequests()
* int printmessage(XD *xd, char *message)
* int Synchronize(XD *xd)
* double MeasureSyncTime(FILE *fp, XD *xd)
* int doublecomp(i,j)
* double median(array, num)
* int ParseCommandLine(int argc, char *argv[], XD *xd)
* int compare(char *str1, char *str2)
*/
static char copyright[] =
"@(#) Copyright (c) 1992 Aloke Gupta.\n\
All rights reserved.\n";
#define VERSION "1.01"
char *xmeasure_version=VERSION;
#include <math.h>
#include "perf.h"
extern TestRequest testrequest[];
double MeasureSyncTime();
char *prog_name; /* Name of this program */
main(argc, argv)
int argc;
char *argv[];
{
XD xd; /* Some parameters of the display server */
prog_name = argv[0];
ParseCommandLine(argc, argv, &xd);
SetupDisplay(&xd);
PrintServerInfo(stdout, &xd, argc, argv);
SetSyncTime(MeasureSyncTime(stdout, &xd));
RunTests(&xd);
printf("\n# ");
PrintTime(stdout);
CleanupDisplay(&xd);
return(0);
}
/*
* Open display and set up the windows
*/
SetupDisplay(xd)
XD *xd;
{
XSizeHints hint;
XSetWindowAttributes xswa;
if ( (xd->display = XOpenDisplay(xd->displayname) ) == NULL) {
fprintf(stderr, "Unable to open display '%s'\n",
XDisplayName(xd->displayname));
Usage("\n");
}
xd->screen = DefaultScreen (xd->display);
xd->cmap = DefaultColormap(xd->display, xd->screen);
xd->visual = DefaultVisual (xd->display, xd->screen);
/*
* Set foreground and background attributes
*/
xd->foreground = BlackPixel(xd->display, xd->screen);
xd->background = WhitePixel(xd->display, xd->screen); /* Default colors */
if (xd->fgname) { /* A command line argument was passed */
XColor xcolor;
if (!XParseColor(xd->display, xd->cmap, xd->fgname, &xcolor))
fprintf(stderr, "Cannot allocate foreground color %s\n",xd->fgname);
else {
XAllocColor(xd->display, xd->cmap, &xcolor);
xd->foreground = xcolor.pixel;
}
}
if (xd->bgname) { /* A command line argument was passed */
XColor xcolor;
if (!XParseColor(xd->display, xd->cmap, xd->bgname, &xcolor))
fprintf(stderr, "Cannot allocate background color %s\n",xd->bgname);
else {
XAllocColor(xd->display, xd->cmap, &xcolor);
xd->background = xcolor.pixel;
}
}
/*
* Disable the screensaver and force the screen to turn on.
* The original settings will be restored eventually.
*/
XForceScreenSaver(xd->display, ScreenSaverReset);
XGetScreenSaver(xd->display, &xd->sstimeout, &xd->ssinterval,
&xd->sspb, &xd->ssae);
XSetScreenSaver(xd->display, 32767, /* X protocol expects INT16 */
xd->ssinterval, xd->sspb, xd->ssae);
/*
* Default positions and size of main window
*/
hint.x = XPOSITION(xd->display, xd->screen);
hint.y = YPOSITION(xd->display, xd->screen);
hint.width = DISPWIDTH;
hint.height = DISPHEIGHT;
hint.flags = PPosition | PSize;
/*
* Create the main window
*/
xd->window = XCreateSimpleWindow(xd->display,DefaultRootWindow(xd->display),
hint.x,hint.y,hint.width,hint.height,1,xd->foreground, xd->background);
if (xd->window == NULL) {
fprintf(stderr, "Could not create main window \n"); fflush(stderr);
exit(1);
}
xswa.override_redirect = True;
xswa.backing_store = False;
xswa.save_under = False;
XChangeWindowAttributes(xd->display, xd->window,
CWOverrideRedirect | CWSaveUnder | CWBackingStore, &xswa);
/*
* Create the message window
*/
xd->msgwindow=XCreateSimpleWindow(xd->display,DefaultRootWindow(xd->display),
hint.x, hint.y - MSGHEIGHT - 4, hint.width, MSGHEIGHT, 1,
xd->foreground, xd->background);
if (xd->msgwindow == NULL) {
fprintf(stderr, "Could not create message window \n"); fflush(stderr);
exit(1);
}
XChangeWindowAttributes(xd->display, xd->msgwindow,
CWOverrideRedirect | CWSaveUnder | CWBackingStore, &xswa);
/*
* Set the Graphics Contexts for the main and message windows
*/
xd->gc = XCreateGC(xd->display, xd->window, 0, 0);
XSetBackground(xd->display, xd->gc, xd->background);
XSetForeground(xd->display, xd->gc, xd->foreground);
xd->msggc = XCreateGC(xd->display, xd->msgwindow, 0, 0);
XSetBackground(xd->display, xd->msggc, xd->background);
XSetForeground(xd->display, xd->msggc, xd->foreground);
/*
* Initialize the array of graphics contexts
*/
InitGCarray(xd);
/*
* Input Event Selection
*/
XSelectInput(xd->display, xd->window,
ButtonPressMask | KeyPressMask | ExposureMask);
/*
* Window Mapping
*/
XMapRaised(xd->display, xd->window);
XMapRaised(xd->display, xd->msgwindow);
/*
* Move the pointer out of the way
*/
ParkPointer(xd);
}
CleanupDisplay(xd)
XD *xd;
{
int i;
printmessage(xd, "Cleaning up display");
XFreeGC(xd->display, xd->gc);
XFreeGC(xd->display, xd->msggc);
for (i=0; i < GFXSLOTS; i++)
XFreeGC(xd->display, xd->gcarray[i]);
XDestroyWindow(xd->display, xd->window);
XDestroyWindow(xd->display, xd->msgwindow);
/* Restore screensaver */
XSetScreenSaver(xd->display, xd->sstimeout, xd->ssinterval,
xd->sspb, xd->ssae);
}
/*
* Move the cursor to a convenient location on the screen
*/
ParkPointer(xd)
XD* xd;
{
int xpos, ypos;
xpos = XPOSITION(xd->display,xd->screen) + DISPWIDTH + 16;
ypos = YPOSITION(xd->display,xd->screen) + (DISPHEIGHT / 2);
XWarpPointer(xd->display, None, DefaultRootWindow(xd->display),
0, 0, 0, 0, xpos, ypos);
}
/*
* Print information about the server contacted
*/
PrintServerInfo(fp, xd, argc, argv)
FILE *fp;
XD *xd;
int argc;
char *argv[];
{
char hostname[128];
char *prefix = "#"; /* Turn line into a comment */
int i;
gethostname(hostname, 128);
fprintf(fp, "%s \"%s\", version %s, running on %s.\n",
prefix, prog_name, xmeasure_version, hostname);
fprintf(fp, "%s Displaying on %s, ", prefix, DisplayString(xd->display));
i = DisplayPlanes(xd->display, xd->screen);
fprintf(fp, "which has %d color plane%c and %d color cells.\n",
i, (i == 1) ? '\0' : 's', DisplayCells(xd->display,xd->screen));
fprintf(fp, "%s %s server Version %d.%d Release %d.\n", prefix,
ServerVendor(xd->display), ProtocolVersion(xd->display),
ProtocolRevision(xd->display), VendorRelease(xd->display));
/*
* Now print out the command line
*/
if (argc > 1) {
fprintf(fp, "%s Command line: \"", prefix);
for (i=0; i < argc; i++)
fprintf(fp, "%s ", argv[i]);
fprintf(fp, "\"\n");
}
/*
* Print the time
*/
fprintf(fp, "%s ", prefix);
PrintTime(fp);
fflush(fp);
}
Usage(errmsg)
char *errmsg;
{
char **ptr;
static char *options[] = { /* Help message */
"where options include:\n",
" -help Print out this help message\n",
" -time <s> Run each test for <s> seconds (default = 1.0)\n",
" -repeat <n> Run each test <n> times (default = 3)\n",
" -<Request Name> Run tests for this X protocol request\n",
" -range <Req1> <Req2> Run tests for all requests in the range specified. \n",
" -all Run tests for all X protocol requests\n",
" -list List the X protocol requests\n",
" -display <dpy> X server on which to display\n",
" -fg <color> Foreground color\n",
" -bg <color> Background color\n",
"\n",
NULL
};
fflush(stdout);
if (errmsg) fprintf(stderr, "%s: %s\n\n", prog_name, errmsg);
fprintf(stderr, "Usage: %s [-options ...]\n", prog_name);
for (ptr = options; *ptr; ptr++)
fprintf(stderr, "%s", *ptr);
exit(1);
}
ListRequests()
{
int count=0, req=0;
fprintf(stderr,"%s: The X protocol request names are:", prog_name);
for (req=0; req < MAXREQUESTS; req++) {
if (strcmp(testrequest[req].name, "Undefined Request")) {
if ((count++ % 3) == 0)
fprintf(stderr,"\n ");
fprintf(stderr,"%-25s", testrequest[req].name);
}
}
fprintf(stderr,"\n");
exit(1);
}
/*
* Print a message in the message window
*/
printmessage(xd, message)
XD *xd;
char *message;
{
XClearWindow(xd->display, xd->msgwindow);
XDrawString (xd->display, xd->msgwindow, xd->msggc, 10,
MSGHEIGHT - (MSGHEIGHT - 10)/2, message, strlen(message) );
}
/*
* Synchronize the server and the client by checking the position of the
* mouse on the screen.
*/
Synchronize(xd)
XD *xd;
{
Window rw,cw;
int xw, yw, xr, yr;
unsigned int keys_buttons;
XQueryPointer(xd->display, DefaultRootWindow(xd->display), &rw, &cw,
&xw, &yw, &xr, & yr, & keys_buttons);
}
/*
* Measure the synchronization time as spent in the Synchronize function
* The result is returned in seconds. The tests are run for 5000 iterations or
* 5 seconds, whichever is earlier.
*/
#define ITNS 5000
#define MAXTIME 5.0 /* At most 5.0 seconds */
#define NUMTIMES 2
double MeasureSyncTime(fp, xd)
FILE *fp;
XD *xd;
{
int numtimes, itns;
double itime, ftime;
double msmt[NUMTIMES];
double retval;
char message[100];
for (numtimes = 0; numtimes < NUMTIMES; numtimes++) {
sprintf(message, "%s. Test %d of %d",
"Measuring client-server synchronization correction",
numtimes+1, NUMTIMES);
printmessage(xd, message);
Synchronize(xd);
/*
* Now run the measurement
*/
itime = gettime();
for (itns = 0; itns < ITNS; itns++) {
Synchronize(xd);
ftime = gettime();
if ( (ftime - itime) > MAXTIME)
break;
}
msmt[numtimes] = (ftime - itime ) / itns;
}
retval = median(msmt, NUMTIMES);
fprintf(fp,"# ");
fprintf(fp,"Synchronization correction %5.2lf ms\n", 1000.0 * retval) ;
return(retval);
}
int doublecomp(i,j)
double *i, *j;
{
int retval=0;
if (*i > *j) retval = 1;
else if (*i < *j) retval = -1;
return(retval);
}
double median(array, num)
double array[];
int num;
{
qsort( (char *) array, num, sizeof(double), doublecomp);
if (num % 2) /* Even number */
return((array[(num-1)/ 2] + array[num/2]) / 2);
else return(array[(num)/2]);
}
ParseCommandLine(argc, argv, xd)
int argc;
char *argv[];
XD *xd;
{
int i, req;
Boolean success=FALSE;
char buffer[80]; /* Communicate error messages to Usage() */
xd->displayname= NULL; /* Initially no displayname is specified */
xd->fgname = NULL;
xd->bgname = NULL;
/*
* Initially disable all requests
*/
for (req=0; req < MAXREQUESTS; req++)
testrequest[req].dothis = FALSE;
/*
* Now parse the command line
*/
for (i=1; i < argc; i++) {
/*
* List legal X requests ?
*/
if (!strcmp(argv[i], "-list"))
ListRequests();
/*
* Print help message ?
*/
if (!strcmp(argv[i], "-help"))
Usage((char *) NULL);
/*
* Which display to use ?
*/
if (!strcmp(argv[i], "-display") || !strcmp (argv[i], "-d")) {
if (++i >= argc)
Usage("need argument to -display");
else xd->displayname = argv[i];
continue;
}
/*
* Set the background color
*/
if (!strcmp(argv[i], "-bg")) {
if (++i >= argc)
Usage("need background color argument to -bg");
xd->bgname = argv[i];
continue;
}
/*
* Set the foreground color
*/
if (!strcmp(argv[i], "-fg")) {
if (++i >= argc)
Usage("need foreground color argument to -fg");
xd->fgname = argv[i];
continue;
}
/*
* How many times to run each test ?
*/
if (!strcmp(argv[i], "-repeat") ) {
int repeats;
if (++i >= argc)
Usage("need argument to -repeat");
else repeats = atoi(argv[i]);
if (repeats == 0)
Usage("illegal argument to -repeat");
SetRepeats(repeats);
continue;
}
/*
* How much time (seconds) to run each test ?
*/
if (!strcmp(argv[i], "-time") ) {
float time;
if (++i >= argc)
Usage("need argument to -time");
else time = (float) atof(argv[i]);
if ( time == 0.0)
Usage("illegal argument to -time");
SetTesttime(time);
continue;
}
/*
* Do them all ?
*/
if (!strcmp(argv[i], "-all")) {
for (req=0; req < MAXREQUESTS; req++)
testrequest[req].dothis = TRUE;
continue;
}
/*
* Range of tests specified ?
*/
if (!strcmp(argv[i], "-range")) {
char *name1, *name2;
int index1 = -1, index2 = -1, tmp;
if (++i >= argc)
Usage("need more arguments to specify -range");
else name1=argv[i];
if (++i >= argc)
Usage("need more arguments to specify -range");
else name2=argv[i];
if (*name1 == '-') name1++;
if (*name2 == '-') name2++;
/* find the indices for name1 and name2 */
for (req=0; req < MAXREQUESTS; req++) {
if (compare(name1, testrequest[req].name) == 0)
index1 = req;
if (compare(name2, testrequest[req].name) == 0)
index2 = req;
if ((index1 != -1) && (index2!= -1))
break;
}
if (index1 == -1) {
sprintf(buffer, "unrecognized request %s", name1);
Usage(buffer);
}
if (index2 == -1) {
sprintf(buffer, "unrecognized request %s", name2);
Usage(buffer);
}
if (index1 > index2) { /* swap them if necessary */
tmp = index1; index1 = index2; index2 = tmp;
}
/* Now enable the range specified */
for (req=index1; req <= index2; req++)
testrequest[req].dothis = TRUE;
continue;
}
/*
* Check each legal test
*/
for (req=0; req < MAXREQUESTS; req++) {
if (compare(argv[i]+1, testrequest[req].name) == 0) {
success = testrequest[req].dothis = TRUE;
break;
}
}
if (success == TRUE) {/* Reset success, if true, and continue parsing */
success=FALSE;
continue;
}
/*
* If we have reached this far, this is a meaningless option
*/
sprintf(buffer, "unrecognized option: %s", argv[i]);
Usage(buffer);
}
}
/* Case insensitive comparison of two strings */
/* Returns zero if the two strings are the same */
compare(str1, str2)
char *str1;
char *str2;
{
char c1, c2;
while (*str1 && *str2) {
c1 = *str1++;
c2 = *str2++;
if (isupper(c1) ) c1 = tolower(c1);
if (isupper(c2) ) c2 = tolower(c2);
if (c1 != c2)
return (-1);
}
if (*str1 || *str2)
return (-1);
else return(0);
}